package com.homework.linglong.config;

import com.homework.linglong.common.service.MyPasswordEncoder;
import com.homework.linglong.handler.RestAuthenticationEntryPoint;
import com.homework.linglong.handler.RestLoginFailureHandler;
import com.homework.linglong.handler.RestfulAccessDeniedHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.AccessDeniedHandler;


/**
 * 对SpringSecurity的配置的扩展
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    public static final String ROLE_USER = "USER";
    public static final String ROLE_ADMIN = "ADMIN";

    @Autowired
    PasswordEncoder passwordEncoder;

    @Qualifier("userServiceImpl")
    @Autowired
    UserDetailsService userDetailsService;
    /**
     * 配置安全策略，使用此放行请求
     * @param http:
     * @throws Exception:
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        var  registry = http.authorizeRequests();
        http.formLogin()
                .loginPage("/auth/login")
                .usernameParameter("username")
                .passwordParameter("password")
                .failureHandler(restLoginFailureHandler())
                .and()
                .logout()
                .logoutUrl("/log_out");
        registry//配置身份验证
                .antMatchers("/user/**")
                .hasRole(ROLE_USER)
                .and()
                .authorizeRequests()
                .antMatchers("/admin/**")
                .hasRole(ROLE_ADMIN);
        http.exceptionHandling()
                .accessDeniedHandler(restfulAccessDeniedHandler());
               // .authenticationEntryPoint(restAuthenticationEntryPoint());
        http.csrf().disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new MyPasswordEncoder();
    }

    @Bean
    public AccessDeniedHandler restfulAccessDeniedHandler() {
        return new RestfulAccessDeniedHandler();
    }

    @Bean
    public RestAuthenticationEntryPoint restAuthenticationEntryPoint() {
        return new RestAuthenticationEntryPoint();
    }

    @Bean
    public RestLoginFailureHandler restLoginFailureHandler(){
        return new RestLoginFailureHandler();
    }
}
